import type { StyleBaseInjector } from './base'
import { logger } from '../../types/constants'
import { StyleInjectPosition, SYMBOLS } from '../../types/interfaces'
import { CrossFrameworkInjector } from './service/cross_injector'
import { IframeInjector } from './service/iframe_injector'
import { ShadowInjector } from './service/shadow_injector'
import { StandardInjector } from './service/standard_injector'

/**
 * 样式标签创建选项
 */
export type StyleElementType = Element | ShadowRoot | Document | null | undefined
export interface StyleTagOptions {
  onlyCreate?: boolean
  allowEmpty?: boolean
  allowUpdate?: boolean
  position?: StyleInjectPosition
  override?: boolean
  targetElement?: StyleElementType

  // CrossFrameworkInjector 参数
  retryCount?: number

  // ShadowRoot 相关选项
  multipleHosts?: boolean
}

/**
 * 注入器类型枚举
 */
export enum InjectorType {
  Standard = 'standard',
  Shadow = 'shadow',
  CrossFramework = 'cross-framework',
  Iframe = 'iframe',
}

/**
 * 样式注入器管理器
 * 统一管理各种类型的样式注入器
 */
export class StyleInjectorManager {
  private readonly name: string = 'StyleInjectorManager'
  private static instance: StyleInjectorManager
  private injectors: Map<InjectorType, StyleBaseInjector> = new Map()
  private defaultInjector: InjectorType = InjectorType.Standard

  private constructor() {
    this.initializeInjectors()
  }

  /**
   * 获取单例实例
   */
  static getInstance(): StyleInjectorManager {
    if (!StyleInjectorManager.instance) {
      StyleInjectorManager.instance = new StyleInjectorManager()
    }
    return StyleInjectorManager.instance
  }

  /**
   * 初始化所有注入器
   */
  private initializeInjectors(): void {
    this.injectors.set(InjectorType.Standard, new StandardInjector())
    this.injectors.set(InjectorType.Shadow, new ShadowInjector())
    this.injectors.set(InjectorType.CrossFramework, new CrossFrameworkInjector())
    this.injectors.set(InjectorType.Iframe, new IframeInjector())

    logger.important(`[${this.name}] 样式注入器管理器初始化完成`)
  }

  /**
   * 获取指定类型的注入器
   */
  getInjector(type: InjectorType): StyleBaseInjector {
    const injector = this.injectors.get(type)

    if (!injector) {
      logger.warn(`[${this.name}] 注入器不存在: ${type}，使用默认注入器`)
      return this.injectors.get(this.defaultInjector)!
    }

    return injector
  }

  /**
   * 设置默认注入器类型
   */
  setDefaultInjector(type: InjectorType): void {
    if (this.injectors.has(type)) {
      this.defaultInjector = type
      logger.info(`[${this.name}] 设置默认注入器: ${type}`)
    }
    else {
      logger.error(`[${this.name}] 注入器不存在: ${type}`)
    }
  }

  /**
   * 创建样式标签（使用默认注入器）
   */
  createStyleTag(
    id: string,
    content: string,
    options?: StyleTagOptions,
  ): HTMLStyleElement | null {
    const injector = this.getInjector(this.defaultInjector)
    return injector.createStyleTag(id, content, options)
  }

  /**
   * 创建样式标签（指定注入器类型）
   */
  createStyleTagWithType(
    type: InjectorType,
    id: string,
    content: string,
    options?: StyleTagOptions,
  ): HTMLStyleElement | null {
    const injector = this.getInjector(type)
    return injector.createStyleTag(id, content, options)
  }

  /**
   * 批量创建样式标签
   */
  batchCreateStyleTags(
    definitions: Array<{
      type: InjectorType
      id: string
      content: string
      options?: StyleTagOptions
    }>,
  ): Map<string, HTMLStyleElement | null> {
    const results = new Map<string, HTMLStyleElement | null>()

    definitions.forEach(({ type, id, content, options }) => {
      const style = this.createStyleTagWithType(type, id, content, options)
      results.set(id, style)
    })

    logger.info(`${SYMBOLS.UI.BOOKMARK} 批量创建 ${definitions.length} 个样式标签`)
    return results
  }

  /**
   * 移除样式标签
   */
  removeStyleTag(id: string, options?: { type?: InjectorType }): boolean {
    const { type } = options || {}

    if (type) {
      const injector = this.getInjector(type)
      return injector.removeStyleTag(id)
    }

    // 尝试在所有注入器中移除
    let removed = false
    this.injectors.forEach((injector) => {
      if (injector.removeStyleTag(id)) {
        removed = true
      }
    })

    return removed
  }

  /**
   * 更新样式内容
   */
  updateStyle(
    id: string,
    content: string,
    type?: InjectorType,
    options?: StyleTagOptions,
  ): boolean {
    if (type) {
      const injector = this.getInjector(type)
      return injector.updateStyle(id, content, options)
    }

    // 尝试在所有注入器中更新
    let updated = false
    this.injectors.forEach((injector) => {
      if (injector.updateStyle(id, content, options)) {
        updated = true
      }
    })

    return updated
  }

  /**
   * 获取所有注入器状态
   */
  getInjectorStatus(): Map<InjectorType, { available: boolean, description: string }> {
    const status = new Map<InjectorType, { available: boolean, description: string }>()

    this.injectors.forEach((_injector, type) => {
      status.set(type, {
        available: true, // 实际应该检查注入器是否可用
        description: this.getInjectorDescription(type),
      })
    })

    return status
  }

  /**
   * 清理所有注入器的样式
   */
  cleanupAll(): void {
    const removedCount = 0

    this.injectors.forEach((injector) => {
      injector.destroy()
    })

    logger.info(`${SYMBOLS.UI.BOOKMARK} 清理完成，移除了 ${removedCount} 个样式`)
  }

  private getInjectorDescription(type: InjectorType): string {
    const descriptions = {
      [InjectorType.Standard]: '标准文档样式注入器',
      [InjectorType.Shadow]: 'Shadow DOM 样式注入器',
      [InjectorType.CrossFramework]: '跨框架样式注入器',
      [InjectorType.Iframe]: 'iframe 样式注入器',
    }
    return descriptions[type] || '未知注入器'
  }
}

/**
 * 创建标准样式标签
 */
export function createStandardStyleTag(
  id: string,
  content: string,
  options?: StyleTagOptions,
): HTMLStyleElement | null {
  return StyleInjectorManager.getInstance().createStyleTagWithType(InjectorType.Standard, id, content, {
    ...options,
    position: options?.position ?? StyleInjectPosition.First,
  })
}

/**
 * 移除标准样式标签
 */
export function removeStandardStyleTag(id: string): boolean {
  return StyleInjectorManager.getInstance().removeStyleTag(id, {
    type: InjectorType.Standard,
  })
}
